package com.lambkit.module.upms;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import com.lambkit.core.Attr;
import com.lambkit.core.Lambkit;
import com.lambkit.db.IRowData;
import com.lambkit.db.PageData;
import com.lambkit.db.RowData;
import com.lambkit.db.RowModel;
import com.lambkit.db.sql.Example;
import com.lambkit.module.dms.service.DmsSqlTemplateService;
import com.lambkit.module.upms.row.*;
import com.lambkit.module.upms.service.*;
import com.lambkit.module.upms.sql.UpmsRolePermissionSQL;
import com.lambkit.module.upms.sql.UpmsUserPermissionSQL;
import com.lambkit.module.upms.sql.UpmsUserSQL;
import com.lambkit.util.Printer;
import com.lambkit.util.StringKit;

import java.util.List;
import java.util.Map;

/**
 * @author yangyong(孤竹行)
 */
public class UpmsApiService {
    private static Log _log = Log.get(UpmsApiService.class);

    public <T extends RowModel<T>> List<T> find(String tamplate_name, Class<T> clazz, Attr data) {
        UpmsConfig config = Lambkit.config(UpmsConfig.class);
        String dbPoolName = config.getDbPoolName();
        return Lambkit.get(DmsSqlTemplateService.class).find(tamplate_name, dbPoolName, clazz, data);
    }

    public <T extends RowModel<T>> T findFirst(String tamplate_name, Class<T> clazz, Attr data) {
        UpmsConfig config = Lambkit.config(UpmsConfig.class);
        String dbPoolName = config.getDbPoolName();
        return Lambkit.get(DmsSqlTemplateService.class).findFirst(tamplate_name, dbPoolName, clazz, data);
    }

    public Boolean queryHasData(String tamplate_name, Attr data) {
        UpmsConfig config = Lambkit.config(UpmsConfig.class);
        String dbPoolName = config.getDbPoolName();
        RowData rowData = Lambkit.get(DmsSqlTemplateService.class).findFirst(tamplate_name, dbPoolName, RowData.class, data);
        return rowData != null ? true : false;
    }

    /**
     * 根据用户id获取所拥有的权限
     * @param upmsUserId
     * @return
     */
    public List<UpmsPermission> selectUpmsPermissionByUpmsUserId(Long upmsUserId) {
        // 用户不存在或锁定状态
        UpmsUser upmsUser = Lambkit.get(UpmsUserService.class).findByPrimaryKey(upmsUserId);
        if (null == upmsUser || 1 == upmsUser.getLocked()) {
            _log.info("selectUpmsPermissionByUpmsUserId : upmsUserId={}", upmsUserId);
            return null;
        }
        Attr data = Attr.by("userId", upmsUserId);
        return find("upms.selectUpmsPermissionByUpmsUserId", UpmsPermission.class, data);
    }


    /**
     * 根据用户id获取所拥有的权限
     * @param upmsUserId
     * @return
     */

    //@Cacheable(value = "zheng-upms-rpc-service-ehcache", key = "'selectUpmsPermissionByUpmsUserId_' + #upmsUserId")
    public List<UpmsPermission> selectUpmsPermissionByUpmsUserIdByCache(Long upmsUserId) {
        return selectUpmsPermissionByUpmsUserId(upmsUserId);
    }

    /**
     * 根据用户id获取所属的角色
     * @param upmsUserId
     * @return
     */

    public List<UpmsRole> selectUpmsRoleByUpmsUserId(Long upmsUserId) {
        // 用户不存在或锁定状态
        UpmsUser upmsUser = Lambkit.get(UpmsUserService.class).findByPrimaryKey(upmsUserId);
        if (null == upmsUser || 1 == upmsUser.getLocked()) {
            _log.info("selectUpmsRoleByUpmsUserId : upmsUserId={}", upmsUserId);
            return null;
        }
        Attr data = Attr.by("userId", upmsUserId);
        return find("upms.selectUpmsRoleByUpmsUserId", UpmsRole.class, data);
    }

    /**
     * 根据用户id获取所属的角色
     * @param upmsUserId
     * @return
     */

    //@Cacheable(value = "zheng-upms-rpc-service-ehcache", key = "'selectUpmsRoleByUpmsUserId_' + #upmsUserId")
    public List<UpmsRole> selectUpmsRoleByUpmsUserIdByCache(Long upmsUserId) {
        return selectUpmsRoleByUpmsUserId(upmsUserId);
    }

    /**
     * 根据角色id获取所拥有的权限
     * @param upmsRoleId
     * @return
     */

    public List<UpmsRolePermission> selectUpmsRolePermisstionByUpmsRoleId(Long upmsRoleId) {
        Example upmsRolePermissionExample = UpmsRolePermissionSQL.of().andRoleIdEqualTo(upmsRoleId).example();
        List<UpmsRolePermission> upmsRolePermissions = Lambkit.get(UpmsRolePermissionService.class).dao().find(upmsRolePermissionExample);
        return upmsRolePermissions;
    }

    /**
     * 根据用户id获取所拥有的权限
     * @param upmsUserId
     * @return
     */

    public List<UpmsUserPermission> selectUpmsUserPermissionByUpmsUserId(Long upmsUserId) {
        Example upmsUserPermissionExample = UpmsUserPermissionSQL.of()
                .andUserIdEqualTo(new Long(upmsUserId)).example();
        List<UpmsUserPermission> upmsUserPermissions = Lambkit.get(UpmsUserPermissionService.class).dao().find(upmsUserPermissionExample);
        return upmsUserPermissions;
    }

    /**
     * 根据条件获取系统数据
     * @param
     * @return
     */
    public List<UpmsSystem> selectUpmsSystemByExample(Example upmsSystemExample) {
        return Lambkit.get(UpmsSystemService.class).dao().find(upmsSystemExample);
    }

    /**
     * 根据条件获取组织数据
     * @param
     * @return
     */
    public List<UpmsOrganization> selectUpmsOrganizationByExample(Example upmsOrganizationExample) {
        return Lambkit.get(UpmsOrganizationService.class).dao().find(upmsOrganizationExample);
    }

    /**
     * 根据username获取UpmsUser
     * @param username
     * @return
     */

    public UpmsUser selectUpmsUserByUsername(String username) {
        if(StrUtil.isBlank(username)) {
            return null;
        }
        Example upmsUserExample = UpmsUserSQL.of()
                .andUsernameEqualTo(username).example();
        List<UpmsUser> upmsUsers = Lambkit.get(UpmsUserService.class).dao().find(upmsUserExample);
        if (null != upmsUsers && upmsUsers.size() > 0) {
            return upmsUsers.get(0);
        }
        return null;
    }


    public UpmsUser selectUpmsUserByEmail(String email) {
        if(StrUtil.isBlank(email)) {
            return null;
        }
        Example upmsUserExample = UpmsUserSQL.of()
                .andEmailEqualTo(email).example();
        List<UpmsUser> upmsUsers = Lambkit.get(UpmsUserService.class).dao().find(upmsUserExample);
        if (null != upmsUsers && upmsUsers.size() > 0) {
            return upmsUsers.get(0);
        }
        return null;
    }


    public UpmsUser selectUpmsUserByPhone(String phone) {
        if(StrUtil.isBlank(phone)) {
            return null;
        }
        Example upmsUserExample = UpmsUserSQL.of()
                .andPhoneEqualTo(phone).example();
        List<UpmsUser> upmsUsers = Lambkit.get(UpmsUserService.class).dao().find(upmsUserExample);
        if (null != upmsUsers && upmsUsers.size() > 0) {
            return upmsUsers.get(0);
        }
        return null;
    }


    public UpmsUser selectUpmsUserByLoginName(String LoginName) {
        if(Validator.isEmail(LoginName)) {
            return selectUpmsUserByEmail(LoginName);
        } else if(Validator.isMobile(LoginName)) {
            return selectUpmsUserByPhone(LoginName);
        } else {
            return selectUpmsUserByUsername(LoginName);
        }
    }


    public UpmsUser selectUpmsUserByUserId(Long upmsUserId) {
        return Lambkit.get(UpmsUserService.class).findByPrimaryKey(upmsUserId);
    }

    /**
     * 写入操作日志
     * @param record
     * @return
     */

    public int insertUpmsLogSelective(UpmsLog record) {
        return Lambkit.get(UpmsLogService.class).dao().save(record) ? 1 : -1;
    }


    public List<UpmsOrganization> selectUpmsOrganizationByUpmsUserId(Long upmsUserId) {
        // 用户不存在或锁定状态
        UpmsUser upmsUser = Lambkit.get(UpmsUserService.class).findByPrimaryKey(upmsUserId);
        if (null == upmsUser || 1 == upmsUser.getLocked()) {
            _log.info("selectUpmsRoleByUpmsUserId : upmsUserId={}", upmsUserId);
            return null;
        }
        Attr data = Attr.by("userId", upmsUserId);
        return find("upms.selectUpmsOrganizationByUpmsUserId", UpmsOrganization.class, data);
    }


    public List<UpmsUser> selectUpmsUserByRoleId(Long id) {
        if (null == id) {
            _log.info("selectUpmsUserByRoleId : upmsRoleId={}", id);
            return null;
        }
        Attr data = Attr.by("roleId", id);
        return find("upms.selectUpmsUserByRoleId", UpmsUser.class, data);
    }

    public UpmsRole selectUpmsRoleByRoleId(Long roleId) {
        return Lambkit.get(UpmsRoleService.class).findById(roleId);
    }

    /////////////////////////////////////////////////////////////////////////////

    public Boolean hasRole(Long userid, Long roleid) {
        Attr data = Attr.by("userId", userid).set("roleId", roleid);
        return queryHasData("upms.getRoleByUserIdAndRoleId", data);
    }

    public Boolean hasRole(Long userid, String roleName) {
        Attr data = Attr.by("userId", userid).set("roleName", roleName);
        return queryHasData("upms.getRoleByUserIdAndRoleName", data);
    }

    public Boolean lacksRole(String roleName) {
        Attr data = Attr.by("roleName", roleName);
        return queryHasData("upms.lacksRole", data);
    }

    public Boolean hasAnyRoles(Long userid, String roleNames) {
        roleNames = roleNames.startsWith(",") ? roleNames.substring(1) : roleNames;
        roleNames = roleNames.endsWith(",") ? roleNames.substring(0, roleNames.length()-1) : roleNames;
        Attr data = Attr.by("userId", userid).set("roleNames", roleNames.split(","));
        return queryHasData("upms.getRoleByUserIdAndRoleNames", data);
    }

    public Boolean hasAllRoles(Long userid, String roleNames) {
        roleNames = roleNames.startsWith(",") ? roleNames.substring(1) : roleNames;
        roleNames = roleNames.endsWith(",") ? roleNames.substring(0, roleNames.length()-1) : roleNames;
        Attr data = Attr.by("userId", userid).set("names", roleNames.split(","));
        List<UpmsRole> upmsRoles = find("upms.getRoleByUserIdAndRoleNames", UpmsRole.class, data);
        roleNames = "," + roleNames + ",";
        if(upmsRoles!=null && upmsRoles.size() > 0) {
            for (UpmsRole role : upmsRoles) {
                roleNames.replace(","+role.getName()+",", ",");
            }
            if(",".equals(roleNames)) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    public Boolean hasRule(Long userid, Long ruleid) {
        Attr data = Attr.by("userId", userid).set("ruleId", ruleid);
        return queryHasData("upms.getRuleByUserIdAndRuleId", data);
    }

    public Boolean hasRule(Long userid, String permission) {
        Attr data = Attr.by("userId", userid).set("permission", permission);
        return queryHasData("upms.getRuleByUserIdAndPermission", data);
    }

    public Boolean lacksRule(String permission) {
        Attr data = Attr.by("permission", permission);
        return queryHasData("upms.lacksRule", data);
    }

    public Boolean hasAnyRules(Long userid, String permissions) {
        permissions = permissions.startsWith(",") ? permissions.substring(1) : permissions;
        permissions = permissions.endsWith(",") ? permissions.substring(0, permissions.length()-1) : permissions;
        Attr data = Attr.by("userId", userid).set("names", permissions.split(","));
        List<UpmsPermission> rules = find("upms.getRuleOfUserIdAndRuleNames", UpmsPermission.class, data);
        return rules != null && rules.size() > 0 ? true : false;
    }

    public Boolean hasAllRules(Long userid, String permissions) {
        permissions = permissions.startsWith(",") ? permissions.substring(1) : permissions;
        permissions = permissions.endsWith(",") ? permissions.substring(0, permissions.length()-1) : permissions;
        Attr data = Attr.by("userId", userid).set("names", permissions.split(","));
        List<UpmsPermission> rules = find("upms.getRuleOfUserIdAndRuleNames", UpmsPermission.class, data);
        permissions = "," + permissions + ",";
        if(rules!=null && rules.size() > 0) {
            for (UpmsPermission rule : rules) {
                permissions.replace(","+rule.getName()+",", ",");
            }
            if(",".equals(permissions)) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    public Boolean isGuestRule(String permission) {
        Attr data = Attr.by("permission", permission);
        return queryHasData("upms.isGuestRuleByPermission", data);
    }
}
